﻿using AutoMapper;
using Furion;
using Furion.DependencyInjection;
using Furion.LinqBuilder;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using XinGuanERP.Db;
using XinGuanERP.Models.Po.system;
using XinGuanERP.Models.Vo.system;
using XinGuanERP.Services.system.IServices;
using XinGuanERP.Utils;

namespace XinGuanERP.Services.system
{
    public class DictService : IDictService, ITransient
    {
        private readonly DefaultDbContext _defaultDbContext;

        public DictService(DefaultDbContext defaultDbContext)
        {
            _defaultDbContext = defaultDbContext;
        }

        public bool DeleteDict(string Id)
        {
            var res = _defaultDbContext.Dicts.FirstOrDefault(t => t.Id == Id);
            var dictEntriesRes = _defaultDbContext.DictEntries.Where(
                t => t.DictId == res!.Id).ToList();

            if (res != null)
            {
                _defaultDbContext.Dicts.Remove(res);
                if (dictEntriesRes.Count > 0)
                {
                    _defaultDbContext.DictEntries.RemoveRange(dictEntriesRes);
                }
                return _defaultDbContext.SaveChanges() > 0;
            }
            else
            {
                return false;
            }
        }

        public List<DictVo> GetDictWithList()
        {
            var res = new List<Dict>();
            res = _defaultDbContext.Dicts.ToList();
            List<DictVo> viewDicts = new();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<Dict, DictVo>()
                .ForMember(dest => dest.NameCode, opt => opt.MapFrom(src => src.Name + "  " + src.Code)));
            var mapper = config.CreateMapper();
            foreach (var dict in res)
            {
                var dest = mapper.Map<DictVo>(dict);
                viewDicts.Add(dest);
            }
            return viewDicts;
        }

        public PageResult<DictVo> GetDictWithPage(int page, int pageSize, string? Name, string? Code)
        {
            var res = new List<Dict>();
            var count = 0;
            var sql = _defaultDbContext.Dicts.AsQueryable();
            if (!Name.IsNullOrEmpty() && Code.IsNullOrEmpty())
            {
                res = sql.Where(d =>
                        EF.Functions.Like(d.Name, "%" + Name + "%"))
                    .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                count = sql.Where(d =>
                        EF.Functions.Like(d.Name, "%" + Name + "%"))
                    .Count();
            }

            if (!Code.IsNullOrEmpty() && Name.IsNullOrEmpty())
            {
                res = sql.Where(d =>
                        EF.Functions.Like(d.Code, "%" + Code + "%"))
                    .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                count = sql.Where(d =>
                        EF.Functions.Like(d.Code, "%" + Code + "%"))
                    .Count();
            }

            if (!Name.IsNullOrEmpty() && !Code.IsNullOrEmpty())
            {
                res = sql.Where(d =>
                        EF.Functions.Like(d.Name, "%" + Name + "%"))
                    .Where(d =>
                        EF.Functions.Like(d.Code, "%" + Code + "%"))
                    .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                count = sql.Where(d =>
                        EF.Functions.Like(d.Name, "%" + Name + "%"))
                    .Where(d =>
                        EF.Functions.Like(d.Code, "%" + Code + "%"))
                    .Count();
            }

            if (Name.IsNullOrEmpty() && Code.IsNullOrEmpty())
            {
                res = sql.Skip((page - 1) * pageSize).Take(pageSize).ToList();
                count = sql.Count();
            }

            List<DictVo> viewDicts = new();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<Dict, DictVo>());
            var mapper = config.CreateMapper();
            foreach (var dict in res)
            {
                var dest = mapper.Map<DictVo>(dict);
                viewDicts.Add(dest);
            }

            return new PageResult<DictVo>()
            {
                Items = viewDicts,
                Total = count
            };
        }

        public bool UpdateDict(DictVo viewDict)
        {
            var res = _defaultDbContext.Dicts.FirstOrDefault(d => d.Id == viewDict.Id);
            var config = new MapperConfiguration(cfg => cfg.CreateMap<DictVo, Dict>()
                .BeforeMap((src, des) => src.Id = Guid.NewGuid().ToString().Replace("-", "").ToUpper())
                .BeforeMap((src, des) => des.CreateTime = DateTime.Now)
                .BeforeMap((src, des) => des.CreateUserId = App.User?.FindFirstValue("UserId"))
                .BeforeMap((src, des) =>
                    des.CreateUserName = App.User?.FindFirstValue("UserName")));
            var mapper = config.CreateMapper();
            if (res == null)
            {
                _defaultDbContext.Dicts.Add(
                        mapper.Map<Dict>(viewDict)
                );
            }
            else
            {
                res = new MapperConfiguration(cfg => cfg.CreateMap<DictVo, Dict>()
                    .BeforeMap((src, des) => des.UpdateTime = DateTime.Now)
                    .BeforeMap((src, des) =>
                        des.UpdateUserId = App.User?.FindFirstValue("UserId"))
                    .BeforeMap((src, des) =>
                        des.UpdateUserName = App.User?.FindFirstValue("UserName")))
                    .CreateMapper().Map(viewDict, res);
            }

            return _defaultDbContext.SaveChanges() > 0;
        }
    }
}
